package com.okilo.online.app.act

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.CountDownTimer
import android.view.View
import android.widget.LinearLayout
import androidx.recyclerview.widget.GridLayoutManager
import com.okilo.online.app.R
import com.okilo.online.app.common.OkiloComAct
import com.okilo.online.app.databinding.OkiloActApplyBinding
import com.okilo.online.app.databinding.OkiloActApplyDetailsChildItemBinding
import com.okilo.online.app.databinding.OkiloActApplyDetailsItemBinding
import com.okilo.online.app.event.OkiloEventData
import com.okilo.online.app.event.OkiloEventPointType
import com.okilo.online.app.event.room.OkiloPointManager
import com.okilo.online.app.tools.OkiloDensityUtil
import com.okilo.online.app.tools.apt.OkiloOnSingleClickListener
import com.okilo.online.app.tools.decoration.GridSpacingItemDecoration
import com.okilo.online.app.tools.extensions.addCommasFromEndRegex
import com.okilo.online.app.tools.helper.OkiloConfigProcessHp
import com.okilo.online.app.apt.OkiloApplyTermApt
import com.okilo.online.app.dialog.OkiloApplySuccessDlog
import com.okilo.online.app.pet.OkiloLoanPet
import com.okilo.online.app.pet.view.IOkiloLoan
import com.okilo.online.app.weight.font.OkiloTextView
import com.okilo.online.app.weight.seekbar.OnRangeChangedListener
import com.okilo.online.app.weight.seekbar.RangeSeekBar
import org.json.JSONArray
import org.json.JSONObject
import java.math.BigDecimal

/**
 * OkiloLoan
 * @Author wwdeng
 * @CreateTime: 2024/9/25 19:21
 * @Annotation：申请贷款
 */
class OkiloApplyAct: OkiloComAct(), IOkiloLoan.IOkiloApply {
    private var _binding: OkiloActApplyBinding? = null
    private var countdownTimer: OkiloApplyCountDownTimer? = null
    //等待时长
    private var countdown = 10 * 60

    //选择的申贷期限
    private var applyTermApt: OkiloApplyTermApt? = null

    private var applyPet: OkiloLoanPet? = null

    companion object {
        fun start(context: Context) {
            val intent = Intent(context, OkiloApplyAct::class.java)
            context.startActivity(intent)
        }
    }

    override val pageName: String = "LoanApply_Page"

    override fun createOkiloContentView(): View? {
        _binding = OkiloActApplyBinding.inflate(layoutInflater)
        return _binding?.root
    }

    override fun initializeOkiloViews() {
        getTitleBarManager()
            .setRootBackgroundColor(getColor(R.color.okilo_color_ffeff1f3))
            .setTitleBarVisibility(View.VISIBLE)
            .setTitle(getString(R.string.okilo_apply_title))
            .setTitleColor(getColor(R.color.okilo_color_black))
            .setBackButtonIcon(R.mipmap.okilo_root_back_icon)
            .setRightButtonIcon(R.mipmap.okilo_root_customer_icon)

        initOkiloApplyRefreshLayout()
        initOkiloApplyTermListView()
        _binding?.okiloApplyContentLayout?.visibility = View.GONE
        _binding?.okiloApplyBottomLayout?.visibility = View.GONE
    }

    override fun setupOkiloEventListeners() {
        super.setupOkiloEventListeners()
        /**
         * 申贷额度选择
         */
        _binding?.okiloApplyAmountSeekBar?.setOnRangeChangedListener(object :
            OnRangeChangedListener {
            override fun onRangeChanged(view: RangeSeekBar?, leftValue: Float, rightValue: Float, isFromUser: Boolean) {
                val leftSeekBar = view?.leftSeekBar
                leftSeekBar?.let {
                    _binding?.okiloApplyAmountText?.text = it.indicatorTextDecimalFormat.format(it.progress).addCommasFromEndRegex()
                }
            }
            override fun onStartTrackingTouch(view: RangeSeekBar?, isLeft: Boolean) {
            }
            override fun onStopTrackingTouch(view: RangeSeekBar?, isLeft: Boolean) {
                val leftSeekBar = view?.leftSeekBar
                leftSeekBar?.let {
                    _binding?.okiloApplyAmountText?.text = it.indicatorTextDecimalFormat.format(it.progress).addCommasFromEndRegex()
                }
                loadOkiloData()
            }
        })

        //提交
        _binding?.okiloApplyButtonSubmit?.setOnClickListener(object : OkiloOnSingleClickListener(){
            override fun onSingleClick(v: View?) {
                addEventPointRequestAction(OkiloEventPointType.OKILO_CLICK_TRACK.LOAN_APPLY_SUBMIT,pageName)
                // TODO: 申贷页提交按钮 需上报所有埋点
                OkiloPointManager.getInstance().manualReport()

                showOkiloLoading()
                applyPet?.subOkiloApplyRequest(this@OkiloApplyAct)
            }
        })
    }

    override fun loadOkiloData() {
        if (applyPet == null){
            applyPet = OkiloLoanPet(this)
        }
        showOkiloLoading()
        applyPet?.gOkiloApplyDetailsRequest(this)
    }

    /* 初始化刷新 */
    private fun initOkiloApplyRefreshLayout() {
        _binding?.okiloApplyRefreshLayout?.setColorSchemeResources(R.color.okilo_color_theme, R.color.okilo_color_ff6200ee)
        _binding?.okiloApplyRefreshLayout?.setOnRefreshListener {
            applyPet?.gOkiloApplyDetailsRequest(this)
        }
    }

    /**
     * 初始化申贷期限列表
     */
    private fun initOkiloApplyTermListView(){
        _binding?.okiloApplyTermListView?.setHasFixedSize(true)
        _binding?.okiloApplyTermListView?.isNestedScrollingEnabled = false
        _binding?.okiloApplyTermListView?.isFocusableInTouchMode = false //不需要焦点
        val decoration = GridSpacingItemDecoration.Companion.create(
            spanCount = 3,
            spacingDp = 10,
            context = this,
            includeEdge = false,
            includeTop = true,
            includeBottom = false,
            topSpacingType = GridSpacingItemDecoration.TopSpacingType.BETWEEN_ROWS_ONLY
        )
        _binding?.okiloApplyTermListView?.addItemDecoration(decoration)
        val layoutManager = GridLayoutManager(getContext(), 3)
        _binding?.okiloApplyTermListView?.layoutManager = layoutManager
        applyTermApt = OkiloApplyTermApt(_binding?.okiloApplyTermListView)
        _binding?.okiloApplyTermListView?.adapter = applyTermApt
        applyTermApt?.setOnItemChildClickListener { _, _, position ->
            val adapter = applyTermApt ?: return@setOnItemChildClickListener
            val item = adapter.getItem(position) ?: return@setOnItemChildClickListener
            // 检查是否已选中
            if (item.optBoolean("isSelect", false)) return@setOnItemChildClickListener

            checkOkiloApplyTermItemStatus(adapter,position)
        }
    }

    /**
     * 切换申贷期限选中状态
     */
    @SuppressLint("NotifyDataSetChanged")
    private fun checkOkiloApplyTermItemStatus(adapter: OkiloApplyTermApt, position: Int){
        // 更新选中状态
        (0 until adapter.itemCount).forEach { index ->
            adapter.getItem(index)?.put("isSelect", index == position)
        }
        adapter.notifyDataSetChanged()
        //加载数据
        loadOkiloData()
    }

    /**
     * 获取贷款金额
     */
    override fun gOkiloApplyAmount(): String {
        return _binding?.okiloApplyAmountText?.text.toString().replace(",","")
    }

    /**
     * 获取贷款期限
     */
    override fun gOkiloApplyTerm(): String {
        return applyTermApt?.findSelectedItem()?.optString("day") ?: ""
    }

    /**
     * 允许选择贷款额度
     */
    override fun sOkiloApplySelectableAmountsViews(data: JSONObject) {
        //最小可选额度
        var minAmount = BigDecimal(data.optString("minAmount")).stripTrailingZeros().toPlainString()
        //最大值为剩余额度
        val maxAmount = BigDecimal(data.optString("maxAmount")).stripTrailingZeros().toPlainString()
        //显示额度
        val amount = BigDecimal(data.optString("amount")).stripTrailingZeros().toPlainString()
        //颗粒度
        val scale = data.optString("granularity","1000")
        if (minAmount.toFloat() >= maxAmount.toFloat()){
            minAmount = "${maxAmount.toFloat() - scale.toFloat()}"
        }
        _binding?.okiloApplyAmountSeekBar?.setIndicatorTextDecimalFormat(scale)//刻度
        //最大值必须要比最小值大
        _binding?.okiloApplyAmountSeekBar?.setRange(minAmount.toFloat(),maxAmount.toFloat())
        _binding?.okiloApplyAmountSeekBar?.setProgress(amount.toFloat())

        _binding?.okiloApplyMinAmountText?.text = BigDecimal(minAmount).stripTrailingZeros().toPlainString().addCommasFromEndRegex()
        _binding?.okiloApplyMaxAmountText?.text = maxAmount.addCommasFromEndRegex()

        //支持滑动
        _binding?.okiloApplyAmountSeekBar?.isEnabled = true
        _binding?.okiloApplyAmountSeekBar?.leftSeekBar?.setThumbDrawableId(R.drawable.okilo_btn_pressed)

        _binding?.okiloApplyAmountSeekBar?.visibility = View.VISIBLE
        _binding?.okiloApplyMinMaxAmountLayout?.visibility = View.VISIBLE
    }

    /**
     * 不可选择贷款额度
     */
    override fun sOkiloApplyFixedAmountsViews() {
        _binding?.okiloApplyAmountSeekBar?.visibility = View.GONE
        _binding?.okiloApplyMinMaxAmountLayout?.visibility = View.GONE
    }

    /**
     * 设置贷款明细
     */
    override fun sOkiloApplyDetailsList(data: JSONObject) {
        _binding?.okiloApplyContentLayout?.visibility = View.VISIBLE
        _binding?.okiloApplyBottomLayout?.visibility = View.VISIBLE
        startOkiloApplyCountdownTimer()

        //去掉末尾的0
        val amount = BigDecimal(data.optString("amount")).stripTrailingZeros().toPlainString()
        _binding?.okiloApplyAmountText?.text = amount.addCommasFromEndRegex()
//        _binding?.textApplyCurrency.text = data.optString("currency")

        //明细
//        val array = data.optJSONArray("detailItemList")
//        val detailItemList = arrayListOf<JSONObject>()
//        if (array != null){
//            for (i in 0..<array.length()){
//                val item = array.optJSONObject(i)
//                if (item.has("title") && item.optString("title") == "YES"){
//                    detailItemList.add(item)
//                }
//            }
//            for (i in 0..<detailItemList.size){
//                val obj = detailItemList[i]
//                val childArray = JSONArray()
//                var isAddChild = false
//                for (n in 0..<array.length()){
//                    val item = array.optJSONObject(n)
//                    if (obj.optString("showName") == item.optString("showName")){
//                        isAddChild = true
//                        childArray.put(item)
//                        continue
//                    }
//                    if (item.has("title") && item.optString("title") == "YES"){
//                        isAddChild = false
//                        continue
//                    }
//                    if (isAddChild){
//                        childArray.put(item)
//                    }
//                }
//                obj.put("childList",childArray)
//            }
//        }

        //明细
        val array = data.optJSONArray("detailItemList")
        if (array != null){
            val result = mutableListOf<JSONObject>()
            var currentParent: JSONObject? = null
            var currentChildren = JSONArray()

            for (i in 0 until array.length()) {
                val item = array.optJSONObject(i) ?: continue

                if (item.isParentItem()) {
                    // 保存前一个父项（如果存在）
                    currentParent?.put("childList", currentChildren)
                    currentParent?.let { result.add(it) }

                    // 开始新的父项组
                    currentParent = item
                    currentChildren = JSONArray().apply { put(item) }
                } else {
                    // 添加到当前父项的子项列表
                    currentChildren.put(item)
                }
            }
            // 后一个父项
            currentParent?.put("childList", currentChildren)
            currentParent?.let { result.add(it) }
            sOkiloApplyDetailsListViews(result)
        }
    }

    private fun JSONObject.isParentItem(): Boolean {
        return has("title") && optString("title") == "YES"
    }

    /**
     * 设置贷款时长列表
     */
    override fun sOkiloApplyTermList(data: JSONObject){
        applyTermApt?.takeIf { it.itemCount == 0 }?.let { adapter ->
            adapter.data = data.buildTermList()
        }
    }

    private fun JSONObject.buildTermList(): ArrayList<JSONObject> {
        val defaultDays = optString("days")
        val daysArray = optJSONArray("daysArray")
        return when {
            daysArray != null -> daysArray.toDaysListWithDefault(defaultDays)
            else -> arrayListOf(defaultDays.toTermItem(true))
        }
    }

    private fun JSONArray.toDaysListWithDefault(defaultDays: String): ArrayList<JSONObject> {
        val uniqueDays = mutableSetOf(defaultDays)
        for (i in 0 until length()) {
            optString(i).takeIf { it.isNotBlank() }?.let { uniqueDays.add(it) }
        }
        return ArrayList<JSONObject>().apply {
            uniqueDays.forEach { day ->
                add(day.toTermItem(day == defaultDays))
            }
        }
    }

    private fun String.toTermItem(isSelected: Boolean): JSONObject {
        return JSONObject().apply {
            put("day", this@toTermItem)
            put("isSelect", isSelected)
        }
    }

    /**
     * 设置贷款明细
     */
    private fun sOkiloApplyDetailsListViews(detailsList: MutableList<JSONObject>?){
        if (detailsList == null){
            return
        }
        _binding?.okiloApplyDetailsListLayout?.removeAllViews()
        detailsList.forEach {
            val itemBinding = OkiloActApplyDetailsItemBinding.inflate(layoutInflater)
            val params = LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT)
            params.setMargins(0,0,0, OkiloDensityUtil.dp2px(16f))
            itemBinding.detailsItemLayout.layoutParams = params
            val childList = it.optJSONArray("childList")
            if (childList != null){
                for (i in 0..<childList.length()){
                    val childItem = childList.optJSONObject(i)
                    val childView = OkiloActApplyDetailsChildItemBinding.inflate(layoutInflater)
                    childView.textDetailsTitle.text = childItem.optString("showName")
                    childView.textDetailsTitle.setFontType(OkiloTextView.FontType.RBT_MEDIUM)
                    childView.textDetailsTitle.setTextColor(getColor(R.color.okilo_color_ff747378))
                    childView.textDetailsValue.text = childItem.optString("showDetail")
                    childView.textDetailsValue.setTextColor(getColor(R.color.okilo_color_ff222222))
                    childView.viewLine.visibility = View.GONE

                    if (childItem.has("title") && childItem.optString("title") == "YES"){
                        childView.textDetailsTitle.setFontType(OkiloTextView.FontType.RBT_BOLD)
                        childView.textDetailsTitle.setTextColor(getColor(R.color.okilo_color_ff222222))
                        childView.viewLine.visibility = View.VISIBLE
                    }
                    childView.textOldValue.visibility = View.GONE
                    if (childItem.has("oldDetail")){
                        childView.textOldValue.visibility = View.VISIBLE
                        childView.textOldValue.text = childItem.optString("oldDetail")
                    }
                    childView.discountLayout.visibility = View.GONE
                    if (childItem.has("discount")){
                        childView.discountLayout.visibility = View.VISIBLE
                        childView.textDiscount.text = childItem.optString("discount")
                    }
                    itemBinding.detailsItemLayout.addView(childView.root)
                }
            }
            _binding?.okiloApplyDetailsListLayout?.addView(itemBinding.root)
        }
    }

    /**
     * 测试提示申贷成功dialog
     */
    private fun sOkiloApplySuccessDialog(){
        val dialog = OkiloApplySuccessDlog(
            this,
            pageName,
            object : OkiloApplySuccessDlog.IOkiloApplySuccessClickCallback {
                override fun onOkiloButtonCloseClick(view: View?) {
                    onIntent(OkiloApplyWaitAct::class.java)
                    finish()
                }
            })
        dialog.setCancelable(false)
        dialog.setCanceledOnTouchOutside(false)
        dialog.show()
    }

    /**
     * 贷款申请成功
     */
    override fun sOkiloApplySuccess() {
        hideOkiloLoading()
        sOkiloApplySuccessDialog()
    }

    override fun hideOkiloLoading() {
        super.hideOkiloLoading()
        _binding?.okiloApplyRefreshLayout?.isRefreshing = false
    }

    override fun onOkiloPublishEvent(event: OkiloEventData) {
        super.onOkiloPublishEvent(event)
        when(event.eventType){
            OkiloEventData.TYPE.OKILO_PROCESS_REFRESHED -> {
                //需要校验 WhatsApp 或 SMS
                if (OkiloConfigProcessHp.iOkiloCheckWhatsAppFlag() || OkiloConfigProcessHp.iOkiloCheckSmsFlag()){
                    OkiloVerifyMobileAct.Companion.start(this)
                }
                finish()
            }
            OkiloEventData.TYPE.OKILO_HTTP_REQUEST_ERROR -> {
                hideOkiloLoading()
            }
            else -> {

            }
        }
    }

    /**
     * 开启倒计时
     */
    private fun startOkiloApplyCountdownTimer(){
        if (countdownTimer != null){
            countdownTimer?.cancel()
        }
        countdown = 10 * 60
        if (countdownTimer == null){
            countdownTimer = OkiloApplyCountDownTimer(this, countdown.toLong() * 1000, 1000)
        }
        countdownTimer?.start()
    }

    /**
     * 显示状态
     */
    private fun sOkiloApplyCountdownText(){
        val seconds = countdown % 60
        val showSeconds = if (seconds < 10) "0$seconds" else "$seconds"
        val minutes = countdown / 60 % 60
        val showMinutes = if (minutes < 10) "0$minutes" else "$minutes"

        _binding?.okiloApplyMinuteText1?.text = showMinutes.toCharArray()[0].toString()
        _binding?.okiloApplyMinuteText2?.text = showMinutes.toCharArray()[1].toString()
        _binding?.okiloApplySecondText1?.text = showSeconds.toCharArray()[0].toString()
        _binding?.okiloApplySecondText2?.text = showSeconds.toCharArray()[1].toString()
    }

    /**
     * 倒计时结束
     */
    private fun sOkiloApplyCountdownFinish(){
        //倒计时结束，重新加载数据
        loadOkiloData()
    }

    class OkiloApplyCountDownTimer(private val act: OkiloApplyAct, millisInFuture: Long, countDownInterval: Long): CountDownTimer(millisInFuture, countDownInterval) {
        override fun onTick(millisUntilFinished: Long) {
            // 这里每隔一段时间（定时器间隔）会被调用
            // 可以在这里更新UI，显示剩余时间
            act.countdown = (millisUntilFinished / 1000).toInt()
            act.sOkiloApplyCountdownText()
        }
        override fun onFinish() {
            // 倒计时完成时被调用
            act.sOkiloApplyCountdownFinish()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        if (countdownTimer != null){
            countdownTimer?.cancel()
            countdownTimer = null
        }
    }
}